home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 351-375 / disk_351 / pdc / libsrc.lzh / LibSrc / StdIO / fscanf.c < prev    next >
C/C++ Source or Header  |  1990-04-07  |  8KB  |  314 lines

  1. /*
  2.  * Libraries and headers for PDC release 3.3 (C) 1989 Lionel Hummel.
  3.  * PDC Software Distribution (C) 1989 Lionel Hummel and Paul Petersen.
  4.  * PDC I/O Library (C) 1987 by J.A. Lydiatt.
  5.  *
  6.  * This code is freely redistributable upon the conditions that this 
  7.  * notice remains intact and that modified versions of this file not
  8.  * be included as part of the PDC Software Distribution without the
  9.  * express consent of the copyright holders.  No warrantee of any
  10.  * kind is provided with this code.  For further information, contact:
  11.  *
  12.  *  PDC Software Distribution    Internet:                     BIX:
  13.  *  P.O. Box 4006             or hummel@cs.uiuc.edu            lhummel
  14.  *  Urbana, IL  61801-8801       petersen@uicsrd.csrd.uiuc.edu
  15.  */
  16.  
  17. /*
  18.     fscanf.c - Routines for formatted Input (non-FP version)
  19.  
  20.     This file is a public domain contribution from Jeff Lydiatt
  21.  
  22.     sscanf(buf, fmt, args)            Scan from a memory buffer
  23.         char           *buf, *fmt;
  24.         void           *args;
  25.  
  26.     fscanf(fp, fmt, args)            Scan from a file pointer
  27.         FILE           *fp;
  28.         char           *fmt;
  29.         void           *args;
  30.  
  31.     scanf(fmt, args)            Scan from stdin
  32.         char           *fmt;
  33.         void           *args;
  34. */
  35.  
  36. #include <stdio.h>
  37. #include <varargs.h>
  38. #include <ctype.h>
  39.  
  40. #define TRUE    1
  41. #define FALSE   0
  42.  
  43. _scanchar(fp, buffer)
  44.     FILE           *fp;
  45.     char          **buffer;
  46. {
  47.     char           *ptr;
  48.  
  49.     if (fp != NULL)
  50.         return (fgetc(fp));
  51.     else if (*buffer != NULL) {
  52.         ptr = *buffer;
  53.         if (*ptr == '\0')
  54.             return (EOF);
  55.         else {
  56.             *buffer += 1;
  57.             return (*ptr);
  58.         }
  59.     }
  60.     return (EOF);
  61. }
  62.  
  63.  
  64. _unscanc(fp, buffer, ch)
  65.     FILE           *fp;
  66.     char          **buffer, ch;
  67. {
  68.     char           *ptr;
  69.  
  70.     if (fp != NULL)
  71.         ungetc(ch, fp);
  72.     else if (*buffer != NULL) {
  73.         *buffer -= 1;
  74.         **buffer = ch;
  75.     }
  76. }
  77.  
  78.  
  79. _scanstr(fp, buffer, str, maxlen)
  80.     FILE           *fp;
  81.     char          **buffer, *str;
  82.     int             maxlen;
  83. {
  84.     int             i, ch;
  85.  
  86.     do {
  87.         ch = _scanchar(fp, buffer);
  88.         if (ch == EOF)
  89.             return (0);
  90.     } while (isspace(ch));
  91.  
  92.     _unscanc(fp, buffer, ch);
  93.  
  94.     for (i = 0; i < maxlen; i++) {
  95.         ch = _scanchar(fp, buffer);
  96.         if (isspace(ch) || ch == EOF)
  97.             goto done;
  98.         *str++ = ch;
  99.     }
  100. done:
  101.     *str = '\0';
  102.     return (i != 0);
  103. }
  104.  
  105.  
  106.  
  107. _scanint(fp, buffer, result, base, maxlen)
  108.     FILE           *fp;
  109.     char          **buffer;
  110.     int            *result, base, maxlen;
  111. {
  112.     int             digit, value = 0;
  113.     int             negative, ch, i;
  114.  
  115.     *result = value;
  116.  
  117.     do {
  118.         ch = _scanchar(fp, buffer);
  119.         if (ch == EOF)
  120.             return (0);
  121.     } while (isspace(ch));
  122.  
  123.     if (!(negative = (ch == '-')))
  124.         _unscanc(fp, buffer, ch);
  125.  
  126.     for (i = 0; i < maxlen; i++) {
  127.         ch = _scanchar(fp, buffer);
  128.         if (ch == EOF)
  129.             goto done;
  130.         if (base == 16) {
  131.             if (isdigit(ch))
  132.                 value = value * base + ch - '0';
  133.             else if (ch >= 'a' && ch <= 'f')
  134.                 value = value * base + ch - 'a' + 10;
  135.             else if (ch >= 'A' && ch <= 'F')
  136.                 value = value * base + ch - 'A' + 10;
  137.             else if (!(i == 1 && (ch == 'X' || ch == 'x'))) {
  138.                 _unscanc(fp, buffer, ch);
  139.                 goto done;
  140.             }
  141.         }
  142.         else {
  143.             digit = ch - '0';
  144.             if ((digit >= 0) && (digit < base))
  145.                 value = value * base + digit;
  146.             else {
  147.                 _unscanc(fp, buffer, ch);
  148.                 goto done;
  149.             }
  150.         }
  151.     }
  152. done:
  153.     if (negative)
  154.         *result = -value;
  155.     else
  156.         *result = value;
  157.     return (i != 0);
  158. }
  159.  
  160.  
  161. _doscan(fmt, args, fp, buffer)
  162.     char           *fmt, *buffer;
  163.     FILE           *fp;
  164.     void           *args;
  165. {
  166.     char            local[128];
  167.     int             ch, maxlen, skip, check;
  168.     int             match = 0;
  169.     char           *aptr = (char *) args;
  170.     char           *fptr = fmt;
  171.     char           *cptr;
  172.     int            *iptr;
  173.     short          *sptr;
  174.     unsigned int   *uptr;
  175.     float          *fdptr;
  176.     double         *dptr, dval;
  177.  
  178.     while (*fptr) {
  179.         check = 0;
  180.         switch (*fptr) {
  181.         case ' ':
  182.         case '\t':
  183.         case '\n':
  184.             check = ' ';
  185.             break;
  186.         case '%':
  187.             fptr++;
  188.             if ((check = (*fptr)) == '%')
  189.                 break;
  190.             check = 0;
  191.             maxlen = 1024;
  192.             if (skip = ((*fptr) == '*'))
  193.                 fptr++;
  194.             if (isdigit(*fptr)) {
  195.                 maxlen = 0;
  196.                 while (isdigit(*fptr)) {
  197.                     maxlen = maxlen * 10 + (*fptr) - '0';
  198.                     fptr++;
  199.                 }
  200.             }
  201.             switch (*fptr) {
  202.             case 'c':
  203.                 ch = _scanchar(fp, &buffer);
  204.                 if (ch == EOF)
  205.                     return (match);
  206.                 if (!skip) {
  207.                     cptr = va_arg(aptr, char *);
  208.                     *cptr = ch;
  209.                     match++;
  210.                 }
  211.                 break;
  212.             case 'd':
  213.             case 'D':
  214.                 if (!_scanint(fp, &buffer, &ch, 10, maxlen))
  215.                     return (match);
  216.                 if (!skip) {
  217.                     iptr = va_arg(aptr, int *);
  218.                     *iptr = ch;
  219.                     match++;
  220.                 }
  221.                 break;
  222.             case 'h':
  223.                 if (!_scanint(fp, &buffer, &ch, 10, maxlen))
  224.                     return (match);
  225.                 if (!skip) {
  226.                     sptr = va_arg(aptr, short *);
  227.                     *sptr = ch;
  228.                     match++;
  229.                 }
  230.                 break;
  231.             case 'l':
  232.             case 'L':
  233.                 ++fptr;
  234.                 break;
  235.             case 'o':
  236.                 if (!_scanint(fp, &buffer, &ch, 8, maxlen))
  237.                     return (match);
  238.                 if (!skip) {
  239.                     iptr = va_arg(aptr, int *);
  240.                     *iptr = ch;
  241.                     match++;
  242.                 }
  243.                 break;
  244.             case 's':
  245.                 if (skip) {
  246.                     if (!_scanstr(fp, &buffer, local, maxlen))
  247.                         return (match);
  248.                 }
  249.                 else {
  250.                     cptr = va_arg(aptr, char *);
  251.                     if (!_scanstr(fp, &buffer, cptr, maxlen))
  252.                         return (match);
  253.                     match++;
  254.                 }
  255.                 break;
  256.             case 'u':
  257.                 if (!_scanint(fp, &buffer, &ch, 10, maxlen))
  258.                     return (match);
  259.                 if (!skip) {
  260.                     uptr = va_arg(aptr, unsigned *);
  261.                     *uptr = ch;
  262.                     match++;
  263.                 }
  264.                 break;
  265.             case 'x':
  266.                 if (!_scanint(fp, &buffer, &ch, 16, maxlen))
  267.                     return (match);
  268.                 if (!skip) {
  269.                     iptr = va_arg(aptr, int *);
  270.                     *iptr = ch;
  271.                     match++;
  272.                 }
  273.                 break;
  274.             default:
  275.                 break;
  276.             }
  277.             break;
  278.         default:
  279.             break;
  280.         }
  281.         fptr++;
  282.         if (check > 0 && !isspace(check)) {
  283.             ch = _scanchar(fp, &buffer);
  284.             if (ch != check)
  285.                 return (match);
  286.         }
  287.     }
  288.     return (match);
  289. }
  290.  
  291. sscanf(buf, fmt, args)
  292.     char           *buf, *fmt;
  293.     void           *args;
  294. {
  295.     FILE            fp;
  296.  
  297.     return (_doscan(fmt, &args, NULL, buf));
  298. }
  299.  
  300. fscanf(fp, fmt, args)
  301.     FILE           *fp;
  302.     char           *fmt;
  303.     void           *args;
  304. {
  305.     return (_doscan(fmt, &args, fp, NULL));
  306. }
  307.  
  308. scanf(fmt, args)
  309.     char           *fmt;
  310.     void           *args;
  311. {
  312.     return (_doscan(fmt, &args, stdin, NULL));
  313. }
  314.